{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程同步的方式手段"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "![6.1](./images/6.1.png)\n",
    "\n",
    "- 核心组件：线程池包含两个关键队列 - 线程缓存队列和任务缓存队列\n",
    "- 同步需求：在多线程环境下操作这两个队列时必须考虑线程同步问题"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程同步的两种场景"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 互斥场景：多个线程对共享资源的排他性访问\n",
    "- 通信场景：线程间需要协作完成特定任务时的信息传递"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程同步的实现方式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 互斥机制：\n",
    "  - `mutex`：最基本的互斥锁，保证临界区代码的原子性执行\n",
    "  - `condition_variable`：条件变量，用于线程间的状态通知\n",
    "  - `semaphore`：信号量，控制对共享资源的访问数量\n",
    "- 通信机制：\n",
    "  - 生产者-消费者模式：通过任务队列实现线程间工作分配\n",
    "  - future/promise：用于异步任务结果的获取和设置"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程池的两种模式"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- fixed模式：\n",
    "  - 线程数量固定，通常根据CPU核心数设置\n",
    "  - 优点：资源消耗稳定，避免线程过多导致的上下文切换开销\n",
    "  - 实现方式：使用mutex+condition_variable管理任务队列\n",
    "- cached模式：\n",
    "  - 线程数量动态增长，但设有上限阈值（如1024）\n",
    "  - 空闲线程超时（如60秒）后自动回收\n",
    "  - 优点：能弹性应对突发流量"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程池的使用接口"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 任务提交：\n",
    "- 结果获取：\n",
    "- 模式设置："
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 线程同步"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 线程互斥"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "- 临界区概念：在多线程编程中，多个线程都想执行的共享代码区域称为临界区，需要特别考虑其线程安全性。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "竞态条件\n",
    "\n",
    "- 定义：当代码片段在多线程环境下执行时，随着线程调度顺序不同而得到不同运行结果的现象。\n",
    "- 特征：\n",
    "  - 不可预测性：线程调度没有固定顺序，不能假设执行先后\n",
    "  - 结果不确定性：相同输入可能产生不同输出\n",
    "- 示例：三个线程分别计算1亿到3亿的加法，正确结果应该唯一，不应随调度顺序变化"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "临界区代码段\n",
    "\n",
    "- 定义：存在竞态条件的代码片段称为临界区代码段\n",
    "- 可重入性：\n",
    "  - 可重入代码：在多线程环境下不存在竞态条件，可安全执行\n",
    "  - 不可重入代码：存在竞态条件，需要特殊处理\n",
    "- 判断标准：检查代码是否会在不同调度顺序下产生不同结果"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "原子操作\n",
    "\n",
    "- 核心要求：临界区代码必须保证原子性执行\n",
    "- 实现方式：\n",
    "  - 互斥锁机制\n",
    "  - 原子类型操作\n",
    "  - 无锁编程技术"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "线程互斥的概念\n",
    "\n",
    "- 互斥锁\n",
    "  - 基本机制：\n",
    "    - 获取锁：进入临界区前获取互斥锁\n",
    "    - 释放锁：离开临界区后释放互斥锁\n",
    "  - 锁类型：\n",
    "    - 悲观锁：获取失败立即阻塞线程（默认方式）\n",
    "    - 乐观锁：使用`try_lock`尝试获取，失败不阻塞\n",
    "  - 内核保证：确保同一时刻只有一个线程能成功获取锁\n",
    "- 智能锁\n",
    "  - `lock_guard`：\n",
    "    - 构造时自动加锁\n",
    "    - 析构时自动解锁\n",
    "    - 不可手动控制锁状态\n",
    "  - `unique_lock`：\n",
    "    - 提供`lock/unlock`方法\n",
    "    - 可与条件变量配合使用\n",
    "    - 更灵活但开销略大\n",
    "- 无锁机制\n",
    "  - CAS原理：Compare-And-Swap原子操作\n",
    "  - 应用场景：\n",
    "    - 无锁队列\n",
    "    - 无锁链表\n",
    "    - 无锁数组\n",
    "  - 潜在问题：\n",
    "    - ABA问题（可通过版本号解决）\n",
    "    - 实现复杂度较高"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`atomic`的使用\n",
    "\n",
    "- 适用场景：简单变量操作（如`count++`）\n",
    "- 传统问题：\n",
    "  - 非原子性：`count++`实际包含\"读取-修改-写入\"三步\n",
    "  - 竞争示例：两个线程执行`count++`可能只增加1\n",
    "- 解决方案：\n",
    "  - 使用`atomic`原子类型\n",
    "  - 避免使用重量级互斥锁\n",
    "- 性能优势：比互斥锁更轻量高效"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "C++17",
   "language": "C++17",
   "name": "xcpp17"
  },
  "language_info": {
   "name": "C++17"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
